package com.winning.bi.jdbc;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.winning.bi.job.JmsJob;
import com.winning.bi.job.OldSqlJob;

/**
 * 精简版任务调度
 * 
 * @author 张大川
 *
 */
public class QuartzUtils {
	final static Logger logger = Logger.getLogger(QuartzUtils.class);

	/**
	 * 十六进制字符串转字节数据
	 * 
	 * @param hexString
	 *            字符串
	 * @return 字节数组
	 */
	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	/**
	 * 字节数组转16进制字符串
	 * 
	 * @param src
	 * @return 字符串
	 */
	public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("0x");
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}

	public static List<ScheduleJob> getAllJob(ClassPathXmlApplicationContext ac) throws SchedulerException {
		Scheduler scheduler = (Scheduler) ac.getBean("schedulerFactoryBean");
		GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
		Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
		List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
		for (JobKey jobKey : jobKeys) {
			List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
			for (Trigger trigger : triggers) {
				ScheduleJob job = new ScheduleJob();
				job.setJobName(jobKey.getName());
				job.setJobGroup(jobKey.getGroup());
				job.setDescription("触发器:" + trigger.getKey());
				Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
				job.setJobStatus(triggerState.name());
				if (trigger instanceof CronTrigger) {
					CronTrigger cronTrigger = (CronTrigger) trigger;
					String cronExpression = cronTrigger.getCronExpression();
					job.setCronExpression(cronExpression);
				}
				jobList.add(job);
			}
		}
		return jobList;
	}

	public static void deleteJob(ClassPathXmlApplicationContext ac, ScheduleJob scheduleJob1) throws SchedulerException {
		Scheduler scheduler = (Scheduler) ac.getBean("schedulerFactoryBean");
		
			//ScheduleJob scheduleJob1 = scheduleJob.get(i);
			JobKey jobKey = JobKey.jobKey(scheduleJob1.getJobName(), scheduleJob1.getJobGroup());
			scheduler.deleteJob(jobKey);
		//}

	}

	/**
	 * 
	 * @param job
	 * @param ac
	 * @param type
	 * @throws SchedulerException
	 */
	public static void addJob(ScheduleJob job, ClassPathXmlApplicationContext ac) throws SchedulerException {
		if (job == null || !ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())) {
			return;
		}

		Scheduler scheduler = (Scheduler) ac.getBean("schedulerFactoryBean");

		logger.debug(scheduler
				+ ".......................................................................................add");
		TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());

		CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

		// 不存在，创建一个

		if (null == trigger) {

			Job type = new JmsJob();
			JobDetail jobDetail = JobBuilder.newJob(type.getClass()).withIdentity(job.getJobName(), job.getJobGroup())
					.build();
			jobDetail.getJobDataMap().put("scheduleJob", job);
			jobDetail.getJobDataMap().put("ac", ac);
			jobDetail.getJobDataMap().put("rowversion", job.getMap().get("markversion").toString());

			CronScheduleBuilder scheduleBuilder = null;
			if (job.getMisfireStatus().equals(ScheduleJob.MISFIRE_STATUS_DO_NOTHING)) {
				scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression())
						.withMisfireHandlingInstructionDoNothing();
			} else if (job.getMisfireStatus().equals(ScheduleJob.MISFIRE_STATUS_FIREANDPROCEED)) {
				scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression())
						.withMisfireHandlingInstructionFireAndProceed();
			} else if (job.getMisfireStatus().equals(ScheduleJob.MISFIRE_STATUS_IGNORE_MISFIRES)) {
				scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression())
						.withMisfireHandlingInstructionIgnoreMisfires();
			} else {
				scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
			}

			if (job.getStartTime() != null & job.getEndTime() != null) {
				trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())
						.withSchedule(scheduleBuilder).startAt(job.getStartTime()).endAt(job.getEndTime()).build();
			} else if (job.getStartTime() != null & job.getEndTime() == null) {
				trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())
						.withSchedule(scheduleBuilder).startAt(job.getStartTime()).build();

			} else if (job.getStartTime() == null & job.getEndTime() != null) {
				trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())
						.withSchedule(scheduleBuilder).endAt(job.getEndTime()).build();

			} else {
				trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())
						.withSchedule(scheduleBuilder).build();
			}
			scheduler.scheduleJob(jobDetail, trigger);

		} else {
			// Trigger已存在，那么更新相应的定时设置

			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());

			// 按新的cronExpression表达式重新构建trigger

			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

			// 按新的trigger重新设置job执行

			scheduler.rescheduleJob(triggerKey, trigger);
		}
	}
}
